/**
 * is a dom manager
 */
Jx.categorize('platform.browser.engine', {

	$extend: 'Jx.lib.Engine',

	$requires: [ 'Jx.data.Collection', 'Jx.lib.Hash' ],

	$actions: [

		'createDefaultView',

		'createDocument',

		'createElement'

	],

	$helpers: {

		'Event': 'Jx.platform.browser.lib.Event',
		
		'Dom': 'Jx.platform.browser.lib.Dom'

	},

	$accessors: {

		detect: 'platform.browser.detection',

		support: 'platform.browser.feature'

	},

	domViews: undefined,

	defaultViews: undefined,

	eventMethods: undefined,

	constructor: function(){

		(this.domViews = Jx.instantiate('Jx.data.Collection')).keyPrefix = 'jx-default-view';

		this.defaultViews = Jx.instantiate('Jx.lib.Hash');

		this.readyCallbacks = [];

		this.$super(arguments);

	},

	onDestroy: function(){

		this.domViews.destroy();

		this.defaultViews.destroy();

		this.$super(arguments);

	},

	onInitialize: function(operation, GLOBAL){

		//-- finalize events
		this.eventMethods = this.$Event.getEventMethodNames(this.support());

	},

	onAfterInitialize: function(operation, GLOBAL){

		//-- register GLOBAL as default view
		var view = this.view = this.createDefaultView(GLOBAL);

		//-- initialize view
		view.on({

			'destroy': this.handleDefaultViewDestroy,

			scope: this

		});

		//-- call ready when ready
		if (view.document.node.readyState == 'complete'){

			this.ready = true;

			this.construct(view);

		} else {

			view.on({

				'load': this.handleDefaultViewLoad,

				scope: this

			});

		}

	},

	onConstruct: function(){



	},

	onCreateDefaultView: function(operation){

		var doms = this.domViews,

			index = doms.add(operation.view),

			key = doms.keyAt(index);

		this.defaultViews.set(key,

			operation.returnValue = Jx.instantiate('Jx.platform.browser.dom.DefaultView', [

				operation.view,
				
				this

			])

		);

	},

	onAfterCreateDefaultView: function(operation){

		operation.returnValue.on({

			'destroy': this.handleViewDestroy,

			scope: this

		});

		delete operation.view;

	},

	onCreateDocument: function(operation){

		this.onCreateDefaultView(operation, operation.view);

		operation.returnValue = operation.returnValue.document;

	},

	onAfterCreateDocument: function(operation){

		delete operation.view;

	},

	onCreateElement: function(operation, element){

		operation.returnValue = operation.document.apply(element);

	},

	onRemoveDefaultView: function(view){

		var doms = this.domViews,

			index = doms.indexOf(view.node),

			key;

		if (index != -1){

			key = doms.keyAt(index);

			this.defaultViews.unset(key);

			doms.removeAt(index);

		}

	},

	handleDefaultViewLoad: function(event){

		this.ready = true;

		this.construct(event.dispatcher.observable);

	},

	handleDefaultViewDestroy: function(event){

		this.destruct();

	},

	handleViewDestroy: function(event){

		if (!this.isDestroyed()){

			this.onRemoveDefaultView(

				event.dispatcher.observable

			);

		}

	},

	allowCreateDefaultView: function(operation, view){
		
		view = this.$Dom.getOwnerView(view);
		
		var found = this.getDefaultView(view);

		if (!found){

			operation.view = view;

		} else {

			operation.returnValue = view;

		}

		return !!view && !found;

	},

	allowCreateDocument: function(operation, doc){
		
		var Dom = this.$Dom,
		
			result = false, view;

		doc = Dom.getOwnerDocument(doc);

		if (doc){
			
			view = Dom.getOwnerView(doc);

			var found = this.getDefaultView(view);

			result = !found;

			if (found){

				operation.returnValue = found.document;

			} else {

				operation.view = view;

			}

		}

		return result;

	},

	allowCreateElement: function(operation, element){

		var doc = this.$Dom.isDom(element, 1) ?

				this.createDocument(element)

				:

				undefined;

		return !!doc && (operation.document = doc);

	},

	getDefaultView: function(view){

		var views = this.defaultViews,

			doms = this.domViews,

			found = undefined;

		if (Jx.isString(view, true)){

			found = views.get(view);

		} else if (view && typeof view == 'object'){

			var index = doms.indexOf(view);

			if (index != -1){

				found = views.get( doms.itemAt(index) );

			}

		}

		return found;

	}







});
